home *** CD-ROM | disk | FTP | other *** search
/ Hot Super Models / Hot Super Models.iso / unix / x11 / xv200.tar / xv-2.00 / xvjpeg.c < prev    next >
C/C++ Source or Header  |  1992-01-02  |  18KB  |  708 lines

  1. #ifdef HAVE_JPEG
  2.  
  3. /*
  4.  * xvjpeg.c - i/o routines for 'jpeg' format pictures
  5.  *
  6.  * LoadJFIF(fname, numcols)  -  loads a JPEG pic, does 24to8 code if nec.
  7.  * WriteJFIF(fp, pic, w, h, rmap, gmap, bmap, numcols, colorstyle)
  8.  */
  9.  
  10. /*
  11.  * LoadJFIF Author: Markus Baur, University of Karlsruhe 
  12.  *                  (s_baur@iravcl.ira.uka.de)
  13.  * This software is provided "as is" without any express or implied warranty.
  14.  */
  15.  
  16. /* WriteJFIF() and JPEG dialog routines written by John Bradley */
  17.  
  18. /*
  19.  * Portions Copyright 1989, 1990, 1991, 1992 by John Bradley and
  20.  *                                The University of Pennsylvania
  21.  *
  22.  * Permission to use, copy, and distribute for non-commercial purposes,
  23.  * is hereby granted without fee, providing that the above copyright
  24.  * notice appear in all copies and that both the copyright notice and this
  25.  * permission notice appear in supporting documentation. 
  26.  *
  27.  * The software may be modified for your own purposes, but modified versions
  28.  * may not be distributed.
  29.  *
  30.  * This software is provided "as is" without any expressed or implied warranty.
  31.  *
  32.  * The author may be contacted via:
  33.  *    US Mail:   John Bradley
  34.  *               GRASP Lab, Room 301C
  35.  *               3401 Walnut St.  
  36.  *               Philadelphia, PA  19104
  37.  *
  38.  *    Phone:     (215) 898-8813
  39.  *    EMail:     bradley@cis.upenn.edu       
  40.  */
  41.  
  42.  
  43. #include "xv.h"
  44. #include "jinclude.h"
  45. #include <setjmp.h>
  46.  
  47.  
  48. /**** Stuff for JPEGDialog box ****/
  49.  
  50. #define JWIDE 280
  51. #define JHIGH 160
  52. #define J_NBUTTS 2
  53. #define J_BOK    0
  54. #define J_BCANC  1
  55. #define BUTTH    24
  56.  
  57. #ifdef __STDC__
  58. static void drawJD(int, int, int, int);
  59. static void clickJD(int, int);
  60. static void doCmd(int);
  61. static void writeJPEG(void);
  62. #else
  63. static void drawJD(), doCmd(), clickJD(), writeJPEG();
  64. #endif
  65. static void jselwxv();
  66. static int writeJFIF();
  67.  
  68.  
  69. /* local variables */
  70. static char *filename;
  71. static int   colorType;
  72. static DIAL  qDial;
  73. static BUTT  jbut[J_NBUTTS];
  74. static byte *image8, *image24;
  75.  
  76. static boolean      greyscale;
  77. static byte        *pic24;
  78. static byte        *CurImagePtr;
  79. static long          filesize;
  80. static jmp_buf      jmpState;
  81. static struct external_methods_struct   e_methods;
  82.  
  83.  
  84. /***************************************************/
  85. void CreateJPEGW()
  86. {
  87.   CARD32     data[2];
  88.   Atom       prop;
  89.  
  90.   jpegW = CreateWindow("xv jpeg", NULL, JWIDE, JHIGH, infofg, infobg);
  91.   if (!jpegW) FatalError("can't create jpeg window!");
  92.  
  93.   data[0] = (CARD32) XInternAtom(theDisp, "WM_DELETE_WINDOW", FALSE);
  94.   data[1] = (CARD32) time((long *)0);
  95.   prop = XInternAtom(theDisp, "WM_PROTOCOLS", FALSE),
  96.   XChangeProperty(theDisp, jpegW, prop, prop,
  97.           32, PropModeReplace, (unsigned char *) data, 2);
  98.  
  99.   XSelectInput(theDisp, jpegW, ExposureMask | ButtonPressMask | KeyPressMask);
  100.  
  101.   DCreate(&qDial, jpegW, 190-2, 10, 80, 100, 1, 100, 75, 5, 
  102.       infofg, infobg, "Quality", "%");
  103.  
  104.   BTCreate(&jbut[J_BOK], jpegW, JWIDE-140-1, JHIGH-10-BUTTH-1, 60, BUTTH, 
  105.        "Ok", infofg, infobg);
  106.  
  107.   BTCreate(&jbut[J_BCANC], jpegW, JWIDE-70-1, JHIGH-10-BUTTH-1, 60, BUTTH, 
  108.        "Cancel", infofg, infobg);
  109.  
  110.   XMapSubwindows(theDisp, jpegW);
  111. }
  112.   
  113.  
  114. /***************************************************/
  115. void JPEGDialog(vis)
  116. int vis;
  117. {
  118.   if (vis) {
  119.     CenterMapWindow(jpegW, jbut[J_BOK].x + jbut[J_BOK].w/2,
  120.             jbut[J_BOK].y + jbut[J_BOK].h/2, JWIDE, JHIGH);
  121.   }
  122.   else     XUnmapWindow(theDisp, jpegW);
  123.   jpegUp = vis;
  124. }
  125.  
  126.  
  127. /***************************************************/
  128. int JPEGCheckEvent(xev)
  129. XEvent *xev;
  130. {
  131.   /* check event to see if it's for one of our subwindows.  If it is,
  132.      deal accordingly, and return '1'.  Otherwise, return '0' */
  133.  
  134.   int rv;
  135.   rv = 1;
  136.  
  137.   if (!jpegUp) return 0;
  138.  
  139.   if (xev->type == Expose) {
  140.     int x,y,w,h;
  141.     XExposeEvent *e = (XExposeEvent *) xev;
  142.     x = e->x;  y = e->y;  w = e->width;  h = e->height;
  143.  
  144.     /* throw away excess expose events for 'dumb' windows */
  145.     if (e->count > 0 && e->window == qDial.win) {}
  146.  
  147.     else if (e->window == jpegW)       drawJD(x, y, w, h);
  148.     else if (e->window == qDial.win)   DRedraw(&qDial);
  149.     else rv = 0;
  150.   }
  151.  
  152.   else if (xev->type == ButtonPress) {
  153.     XButtonEvent *e = (XButtonEvent *) xev;
  154.     int x,y;
  155.     x = e->x;  y = e->y;
  156.  
  157.     if (e->button == Button1) {
  158.       if      (e->window == jpegW)     clickJD(x,y);
  159.       else if (e->window == qDial.win) DTrack(&qDial, x,y);
  160.       else rv = 0;
  161.     }  /* button1 */
  162.     else rv = 0;
  163.   }  /* button press */
  164.  
  165.  
  166.   else if (xev->type == KeyPress) {
  167.     XKeyEvent *e = (XKeyEvent *) xev;
  168.     char buf[128];  KeySym ks;  XComposeStatus status;  
  169.     int stlen;
  170.     
  171.     stlen = XLookupString(e,buf,128,&ks,&status);
  172.     buf[stlen] = '\0';
  173.  
  174.     if (e->window == jpegW) {
  175.       if (stlen) {
  176.     if (buf[0] == '\r' || buf[0] == '\n') { /* enter */
  177.       FakeButtonPress(&jbut[J_BOK]);
  178.     }
  179.     else if (buf[0] == '\033') {            /* ESC */
  180.       FakeButtonPress(&jbut[J_BCANC]);
  181.     }
  182.       }
  183.     }
  184.     else rv = 0;
  185.   }
  186.   else rv = 0;
  187.  
  188.   if (rv==0 && (xev->type == ButtonPress || xev->type == KeyPress)) {
  189.     XBell(theDisp, 50);
  190.     rv = 1;   /* eat it */
  191.   }
  192.  
  193.   return rv;
  194. }
  195.  
  196.  
  197. /***************************************************/
  198. void JPEGSaveParams(fname, col)
  199. char *fname;
  200. int col;
  201. {
  202.   filename = fname;
  203.   colorType = col;
  204. }
  205.  
  206.  
  207. /***************************************************/
  208. static void drawJD(x,y,w,h)
  209. int x,y,w,h;
  210. {
  211.   char *title  = "Save JPEG file...";
  212.   char *title1 = "Set quality value.";
  213.   char *title2 = "Default value: 75%";
  214.   char *title3 = "Useful range 5-95%.";
  215.   int  i;
  216.   XRectangle xr;
  217.  
  218.   xr.x = x;  xr.y = y;  xr.width = w;  xr.height = h;
  219.   XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);
  220.  
  221.   XSetForeground(theDisp, theGC, infofg);
  222.   XSetBackground(theDisp, theGC, infobg);
  223.  
  224.   for (i=0; i<J_NBUTTS; i++) BTRedraw(&jbut[i]);
  225.  
  226.   XDrawString(theDisp, jpegW, theGC, 20, 29, title, strlen(title));
  227.  
  228.   XDrawString(theDisp, jpegW, theGC, 30, 29+LINEHIGH*2,title1,strlen(title1));
  229.   XDrawString(theDisp, jpegW, theGC, 30, 29+LINEHIGH*4,title2,strlen(title2));
  230.   XDrawString(theDisp, jpegW, theGC, 30, 29+LINEHIGH*5,title3,strlen(title3));
  231.  
  232.   XSetClipMask(theDisp, theGC, None);
  233. }
  234.  
  235.  
  236. /***************************************************/
  237. static void clickJD(x,y)
  238. int x,y;
  239. {
  240.   int i;
  241.   BUTT *bp;
  242.  
  243.   /* check BUTTs */
  244.  
  245.   for (i=0; i<J_NBUTTS; i++) {
  246.     bp = &jbut[i];
  247.     if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) break;
  248.   }
  249.  
  250.   if (i<J_NBUTTS) {  /* found one */
  251.     if (BTTrack(bp)) doCmd(i);
  252.   }
  253. }
  254.  
  255.  
  256.  
  257. /***************************************************/
  258. static void doCmd(cmd)
  259. int cmd;
  260. {
  261.   switch (cmd) {
  262.   case J_BOK:    writeJPEG();    JPEGDialog(0);  break;
  263.   case J_BCANC:  JPEGDialog(0);  break;
  264.   default:        break;
  265.   }
  266. }
  267.  
  268.  
  269.  
  270.  
  271.  
  272. /*******************************************/
  273. static void writeJPEG()
  274. {
  275.   FILE *fp;
  276.   int   i, nc, rv;
  277.   register byte *ip, *ep;
  278.   byte *inpix, *bwpic, *rmap, *gmap, *bmap;
  279.  
  280.   /* get the XV image into a format that the JPEG software can grok on.
  281.      Also, open the output file, so we don't waste time doing this format
  282.      conversion if we won't be able to write it out */
  283.  
  284.   inpix = epic;  bwpic = NULL;  rmap = r;  gmap = g;  bmap = b;
  285.   nc = numcols;
  286.  
  287.   /* see if we can open the output file before proceeding */
  288.   fp = OpenOutFile(filename);
  289.   if (!fp) return;
  290.  
  291.   WaitCursor();
  292.   
  293.   bwpic = HandleBWandReduced(colorType, &nc, &rmap, &gmap, &bmap);
  294.   if (bwpic) inpix = bwpic;
  295.  
  296.   /* monocity check.  if the image is mono, save it that way to save space */
  297.  
  298.   if (colorType != F_GREYSCALE) {
  299.     for (i=0; i<nc && rmap[i]==gmap[i] && rmap[i]==bmap[i]; i++);
  300.     if (i==nc) colorType = F_GREYSCALE;    /* made it all the way through */
  301.   }
  302.     
  303.  
  304.   /* first thing to do is build an 8/24-bit Greyscale/TrueColor image
  305.      (meaning: non-colormapped) */
  306.  
  307.   if (colorType == F_GREYSCALE) {   /* build an 8-bit Greyscale image */
  308.     image8 = (byte *) malloc(eWIDE * eHIGH);
  309.     if (!image8) FatalError("writeJPEG: unable to malloc image8\n");
  310.  
  311.     for (i=0,ip=image8,ep=inpix; i<eWIDE * eHIGH; i++, ip++, ep++)
  312.       *ip = MONO(rmap[*ep], gmap[*ep], bmap[*ep]);
  313.   }
  314.  
  315.   else {    /* colorType = some color format */
  316.     image24 = NULL;
  317.     if (colorType == F_FULLCOLOR) image24 = Smooth24();
  318.     if (!image24) {  /* smoothing didn't/not tried.  Use 'stupid' method */
  319.       image24 = (byte *) malloc(eWIDE * eHIGH * 3);
  320.       if (!image24) {  /* this simply isn't going to work */
  321.     FatalError("writeJPEG: unable to malloc image24\n");
  322.       }
  323.  
  324.       for (i=0, ip=image24, ep=inpix; i<eWIDE*eHIGH; i++, ep++) {
  325.     *ip++ = rmap[*ep];
  326.     *ip++ = gmap[*ep];
  327.     *ip++ = bmap[*ep];
  328.       }
  329.     }
  330.   }
  331.  
  332.   if (bwpic) free(bwpic);  /* won't need it anymore */
  333.  
  334.   /* in any event, we've got some valid image.  Do the JPEG Thing */
  335.   rv = writeJFIF(fp);
  336.  
  337.   /* get rid of the greyscale/truecolor image */
  338.   if (colorType == F_GREYSCALE) free(image8);
  339.                            else free(image24);
  340.  
  341.   if (CloseOutFile(fp, filename, rv) == 0) {
  342.     /* everything's cool! */
  343.     DirBox(0);
  344.     LoadCurrentDirectory();
  345.   }
  346.  
  347. }
  348.  
  349.  
  350.  
  351.  
  352. /*********************************************/
  353. /**** INTERFACE CODE FOR THE JPEG LIBRARY ****/
  354. /*********************************************/
  355.  
  356.  
  357.  
  358. /********* JPEG DECOMPRESSION FUNCTIONS **********/
  359.  
  360.  
  361. /**************************************************/
  362. static void d_ui_method_selection(cinfo)
  363.      decompress_info_ptr cinfo;
  364. {
  365.   /* select output colorspace */
  366.   if (cinfo->jpeg_color_space == CS_GRAYSCALE) {
  367.     cinfo->out_color_space = CS_GRAYSCALE;
  368.     SetISTR(ISTR_FORMAT,"Greyscale JPEG. (%ld bytes)", filesize);
  369.     greyscale = TRUE;
  370.   }
  371.   else {
  372.     cinfo->out_color_space = CS_RGB;
  373.     SetISTR(ISTR_FORMAT,"Color JPEG. (%ld bytes)", filesize);
  374.     greyscale = FALSE;
  375.   }
  376.  
  377.   jselwxv(cinfo);
  378. }
  379.  
  380.  
  381. /**************************************************/
  382. static void output_init (cinfo)
  383.      decompress_info_ptr cinfo;
  384. {
  385.   pWIDE = cinfo->image_width;
  386.   pHIGH = cinfo->image_height;
  387.  
  388.   if (cinfo->out_color_space == CS_GRAYSCALE) {
  389.     pic = (byte *) malloc(pWIDE * pHIGH);
  390.     if (!pic) FatalError("Not enough memory for Image");
  391.     CurImagePtr = pic;
  392.   }
  393.   else {
  394.     pic24 = (byte *) malloc(pWIDE * pHIGH * 3);
  395.     if (!pic24) FatalError("Not enough memory for Image");
  396.     CurImagePtr = pic24;
  397.   }
  398. }
  399.  
  400.  
  401. /**************************************************/
  402. static void put_color_map (cinfo, num_colors, colormap)
  403.      decompress_info_ptr cinfo;
  404.      int num_colors;
  405.      JSAMPARRAY colormap;
  406. {
  407.   /* never done, because we let xv quantize colors */
  408.   fprintf(stderr, "put_color_map: this should have never happened.\n");
  409. }
  410.  
  411.  
  412. /**************************************************/
  413. static void put_pixel_rows (cinfo, num_rows, pixel_data)
  414.      decompress_info_ptr cinfo;
  415.      int                 num_rows;
  416.      JSAMPIMAGE          pixel_data;
  417. {
  418.   JSAMPROW ptr0, ptr1, ptr2;
  419.   long col;
  420.   long width = cinfo->image_width;
  421.   int row;
  422.   static unsigned int totrows = 0;
  423.  
  424.   if (cinfo->out_color_space == CS_GRAYSCALE) {
  425.     for (row = 0; row < num_rows; row++) {
  426.       ptr0 = pixel_data[0][row];
  427.       for (col = width; col > 0; col--) {
  428.     *CurImagePtr++ = GETJSAMPLE(*ptr0++);
  429.       }
  430.       totrows++;
  431.       if ((totrows & 0x1f) == 0) WaitCursor();
  432.     }
  433.   }
  434.  
  435.   else {
  436.     for (row = 0; row < num_rows; row++) {
  437.       ptr0 = pixel_data[0][row];
  438.       ptr1 = pixel_data[1][row];
  439.       ptr2 = pixel_data[2][row];
  440.       for (col = width; col > 0; col--) {
  441.     *CurImagePtr++ = GETJSAMPLE(*ptr0++);
  442.     *CurImagePtr++ = GETJSAMPLE(*ptr1++);
  443.     *CurImagePtr++ = GETJSAMPLE(*ptr2++);
  444.       }
  445.       totrows++;
  446.       if ((totrows & 0x1f) == 0) WaitCursor();
  447.     }
  448.   }
  449. }
  450.  
  451.  
  452. /**************************************************/
  453. static void output_term (cinfo)
  454.      decompress_info_ptr cinfo;
  455. {
  456.   /* no work required */
  457. }
  458.  
  459.  
  460. /**************************************************/
  461. static void jselwxv(cinfo)
  462.      decompress_info_ptr cinfo;
  463. {
  464.   cinfo->methods->output_init = output_init;
  465.   cinfo->methods->put_color_map = put_color_map;
  466.   cinfo->methods->put_pixel_rows = put_pixel_rows;
  467.   cinfo->methods->output_term = output_term;
  468. }
  469.  
  470.  
  471. /**************************************************/
  472. static void JPEG_Message (msgtext)
  473.      char *msgtext;
  474. {
  475.   char tempstr[200];
  476.  
  477.   sprintf(tempstr, msgtext,
  478.       e_methods.message_parm[0], e_methods.message_parm[1],
  479.       e_methods.message_parm[2], e_methods.message_parm[3],
  480.       e_methods.message_parm[4], e_methods.message_parm[5],
  481.       e_methods.message_parm[6], e_methods.message_parm[7]);
  482.   SetISTR(ISTR_INFO, tempstr);
  483. }
  484.  
  485.  
  486. /**************************************************/
  487. static void JPEG_Error (msgtext)
  488.      char *msgtext;
  489. {
  490.   char tempstr[200];
  491.  
  492.   sprintf(tempstr, msgtext,
  493.       e_methods.message_parm[0], e_methods.message_parm[1],
  494.       e_methods.message_parm[2], e_methods.message_parm[3],
  495.       e_methods.message_parm[4], e_methods.message_parm[5],
  496.       e_methods.message_parm[6], e_methods.message_parm[7]);
  497.   SetISTR(ISTR_WARNING, tempstr);
  498.   longjmp(jmpState,1);
  499. }
  500.  
  501.  
  502. /*******************************************/
  503. int LoadJFIF(fname,nc)
  504.      char *fname;
  505.      int   nc;
  506. /*******************************************/
  507. {
  508.   int i, rtval;
  509.   struct decompress_info_struct    cinfo;
  510.   struct decompress_methods_struct dc_methods;
  511.  
  512.   /* Set up longjmp for error recovery out of JPEG_Error */
  513.   rtval = setjmp(jmpState);
  514.   if (rtval)
  515.     return rtval;        /* no cleanup attempted -- may be a problem */
  516.  
  517.   /* Set up the input file */
  518.  
  519.   if ((cinfo.input_file = fopen(fname, "r")) == NULL) return 1;
  520.  
  521.   /* figure out the file size (for Informational Purposes Only) */
  522.   fseek(cinfo.input_file, 0L, 2);
  523.   filesize = ftell(cinfo.input_file);
  524.   fseek(cinfo.input_file, 0L, 0);
  525.  
  526.   cinfo.output_file = NULL;    /* only wanna read */
  527.   
  528.   /* Initialize the system-dependent method pointers. */
  529.   cinfo.methods  = &dc_methods;
  530.   cinfo.emethods = &e_methods;
  531.   e_methods.error_exit = JPEG_Error; /* provide my own error/message rtns */
  532.   e_methods.trace_message = JPEG_Message;
  533.   e_methods.trace_level = 0;    /* no tracing, thank you */
  534.   jselvirtmem(&e_methods);      /* memory allocation routines */
  535.   dc_methods.d_ui_method_selection = d_ui_method_selection;
  536.  
  537.   /* Set up default JPEG parameters. */
  538.   j_d_defaults(&cinfo, TRUE);
  539.   
  540.   /* Set up to read a JFIF or baseline-JPEG file. */
  541.   /* A smarter UI would inspect the first few bytes of the input file */
  542.   /* to determine its type. */
  543.   jselrjfif(&cinfo);
  544.   
  545.   /* Do it! */
  546.   jpeg_decompress(&cinfo);
  547.  
  548.   if (greyscale) {
  549.     /* fill in a greyscale colormap */
  550.     for (i=0; i<=255; i++) r[i] = g[i] = b[i] = i;
  551.   }
  552.   else {
  553.     /* Convert to 8 bits depth and free 24 Bit Image */
  554.     Conv24to8(pic24, pWIDE, pHIGH, nc);
  555.     free(pic24);
  556.   };
  557.  
  558.   /* Release memory. */
  559.   j_d_free_defaults(&cinfo, TRUE);
  560.  
  561.   /* Close input file */
  562.   fclose(cinfo.input_file);
  563.   
  564.   sprintf(formatStr, "%dx%d %s JPEG. ", cinfo.image_width, cinfo.image_height, 
  565.       (cinfo.out_color_space == CS_GRAYSCALE) ? "Greyscale " : "Color ");
  566.   
  567.   SetDirRButt(F_FORMAT, F_JPEG);
  568.  
  569.   /* Got it! */
  570.   return 0;
  571. };
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578. /********* JPEG COMPRESSION FUNCTIONS **********/
  579.  
  580.  
  581. /**************************************************/
  582. static void c_ui_method_selection(cinfo)
  583.      compress_info_ptr cinfo;
  584. {
  585.   /* select output colorspace */
  586.   if (colorType == F_GREYSCALE) {
  587.     j_monochrome_default(cinfo);
  588.   }
  589. }
  590.  
  591.  
  592. /**************************************************/
  593. static void input_init (cinfo)
  594.      compress_info_ptr cinfo;
  595. {
  596.   if (colorType == F_GREYSCALE) {
  597.     cinfo->input_components = 1;
  598.     cinfo->in_color_space = CS_GRAYSCALE;
  599.     CurImagePtr = image8;
  600.   }
  601.   else {
  602.     cinfo->input_components = 3;
  603.     cinfo->in_color_space = CS_RGB;
  604.     CurImagePtr = image24;
  605.   }
  606.  
  607.   cinfo->image_width  = eWIDE;
  608.   cinfo->image_height = eHIGH;
  609.   cinfo->data_precision = 8;
  610. }
  611.  
  612.  
  613. /**************************************************/
  614. static void get_input_row(cinfo, pixel_row)
  615.      compress_info_ptr cinfo;
  616.      JSAMPARRAY        pixel_row;
  617. {
  618.   JSAMPROW ptr0, ptr1, ptr2;
  619.   long col;
  620.   static unsigned int totrows = 0;
  621.  
  622.   if (cinfo->input_components == 1) {
  623.     ptr0 = pixel_row[0];
  624.     for (col = cinfo->image_width; col > 0; col--) {
  625.       *ptr0++ = *CurImagePtr++;
  626.     }
  627.     totrows++;
  628.     if ((totrows & 0x1f) == 0) WaitCursor();
  629.   }
  630.  
  631.   else {
  632.     ptr0 = pixel_row[0];
  633.     ptr1 = pixel_row[1];
  634.     ptr2 = pixel_row[2];
  635.     for (col = cinfo->image_width; col > 0; col--) {
  636.       *ptr0++ = *CurImagePtr++;
  637.       *ptr1++ = *CurImagePtr++;
  638.       *ptr2++ = *CurImagePtr++;
  639.     }
  640.     totrows++;
  641.     if ((totrows & 0x1f) == 0) WaitCursor();
  642.   }
  643. }
  644.  
  645.  
  646. /**************************************************/
  647. static void input_term (cinfo)
  648.      compress_info_ptr cinfo;
  649. {
  650.   /* no work required */
  651. }
  652.  
  653.  
  654. /**************************************************/
  655. static void jselrxv(cinfo)
  656.      compress_info_ptr cinfo;
  657. {
  658.   cinfo->methods->input_init = input_init;
  659.   cinfo->methods->get_input_row = get_input_row;
  660.   cinfo->methods->input_term = input_term;
  661. }
  662.  
  663.  
  664.  
  665. /*******************************************/
  666. static int writeJFIF(fp)
  667.      FILE *fp;
  668. {
  669.   int rtval;
  670.   struct compress_info_struct    cinfo;
  671.   struct compress_methods_struct c_methods;
  672.  
  673.   /* Set up longjmp for error recovery out of JPEG_Error */
  674.   rtval = setjmp(jmpState);
  675.   if (rtval)
  676.     return rtval;        /* no cleanup attempted -- may be a problem */
  677.   
  678.   /* Initialize the system-dependent method pointers. */
  679.   cinfo.methods  = &c_methods;
  680.   cinfo.emethods = &e_methods;
  681.   e_methods.error_exit = JPEG_Error; /* provide my own error/message rtns */
  682.   e_methods.trace_message = JPEG_Message;
  683.   e_methods.trace_level = 0;    /* no tracing, thank you */
  684.   jselvirtmem(&e_methods);      /* memory allocation routines */
  685.   c_methods.c_ui_method_selection = c_ui_method_selection;
  686.  
  687.   /* Set up default JPEG parameters. */
  688.   j_c_defaults(&cinfo, qDial.val, FALSE);
  689.  
  690.   /* Select input and output */
  691.   cinfo.input_file  = NULL;
  692.   cinfo.output_file = fp;       /* already open */
  693.   
  694.   jselrxv(&cinfo);        /* we'll be reading from memory */
  695.   jselwjfif(&cinfo);        /* and writing to JFIF file format */
  696.  
  697.   /* Do it! */
  698.   jpeg_compress(&cinfo);
  699.   
  700.   /* Release memory. */
  701.   j_c_free_defaults(&cinfo);
  702.  
  703.   return 0;
  704. }
  705.  
  706.  
  707. #endif  /* HAVE_JPEG */
  708.